using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Diagnostics;

namespace VistaBatterySaver
{
    internal class WMIMethods
    {
        #region network
        internal static List<ManagementObject> GetNetworkAdapters()
        {
            ManagementScope scope = new ManagementScope("root\\cimv2");
            scope.Connect();
            try
            {
                List<ManagementObject> NetworkAdapters = GetWMIResult(scope, "SELECT * from Win32_NetworkAdapter where PhysicalAdapter=true", false);
                if (NetworkAdapters == null || NetworkAdapters.Count == 0)
                    return null;
                else
                {
                    for (int i = 0; i < NetworkAdapters.Count; i++)
                    {
                        ManagementBaseObject o = NetworkAdapters[0].GetMethodParameters("SetPowerState");

                        ManagementOperationObserver obs = new ManagementOperationObserver();
                        obs.Completed += new CompletedEventHandler(obs_Completed);
                        obs.Progress += new ProgressEventHandler(obs_Progress);
                        NetworkAdapters[i].InvokeMethod(obs,"Enable",null);
                        
                    }
                }
            }
            catch (NotSupportedException nse)
            {
                throw new NotSupportedException(nse.Message, nse);
            }
            return null;
        }

        static void obs_Progress(object sender, ProgressEventArgs e)
        {
            Console.WriteLine();
        }

        static void obs_Completed(object sender, CompletedEventArgs e)
        {
            Console.WriteLine();
        }
        #endregion
        #region Brightness
        public static bool IsBrightnessControlSupported
        {
            get
            {
                bool res = false;
                try
                {
                    byte[] b = GetBrightnessLevels();
                    if (b != null)
                        res = true;
                }
                catch 
                {
                    res = false;
                }

                return res;

            }
        }

        static byte[] BrightnessLevels;
        private static ManagementObject BrightnessMethodObject = null;
        static byte[] GetBrightnessLevels()
        {

            ManagementScope scope = new ManagementScope("root\\WMI");
            scope.Connect();

            try
            {
                List<ManagementObject> BrightnessObjects = GetWMIResult(scope, "SELECT * from WmiMonitorBrightness", false);

                if (BrightnessObjects == null || BrightnessObjects.Count == 0)
                {
                    BrightnessLevels = null;
                }
                else
                {
                    ManagementObject BrightnessObject = BrightnessObjects[0];
                    BrightnessLevels = (byte[])BrightnessObject["Level"];

                    List<ManagementObject> BrightnessMethodObjects = GetWMIResult(scope, "SELECT * from WmiMonitorBrightnessMethods", false);
                    BrightnessMethodObject = BrightnessMethodObjects[0];

                }
            }
            catch (NotSupportedException nse)
            {
                throw new NotSupportedException(nse.Message, nse);
            }

            return BrightnessLevels;
        }

        static bool SetBrightness(int Percent)
        {
            if (BrightnessLevels == null)
                return false;
            Percent = Math.Min(100, Math.Max(0, Percent));

            ManagementScope scope = new ManagementScope("root\\WMI");
            scope.Connect();

            int ClosestBrightness = BrightnessLevels[0];

            foreach (int level in BrightnessLevels)
            {
                if (Math.Abs(level - Percent) < Math.Abs(ClosestBrightness - Percent))
                    ClosestBrightness = level;
            }

            if (ClosestBrightness != Percent)
                Debug.Print("Closest brightness to {0}% is {1}%.", Percent, ClosestBrightness);

            BrightnessMethodObject.InvokeMethod("WmiSetBrightness", new object[] { (Int64)0, (byte)ClosestBrightness });

            return true;
        }
        #endregion
        static List<ManagementObject> GetWMIResult(ManagementScope scope, string query, bool noisy)
        {
            query = query.Replace(@"\", @"\\");
            if (noisy)
            {
                Debug.Print("Executing query: " + query);
                Debug.Flush();
            }
            ManagementObjectSearcher WMI;
            if (scope == null)
                WMI = new ManagementObjectSearcher(query);
            else
                WMI = new ManagementObjectSearcher(scope, new ObjectQuery(query));

            ManagementObjectCollection objectCollection = WMI.Get();
            List<ManagementObject> objects = new List<ManagementObject>();
            try
            {
                objects.Capacity = objectCollection.Count;
                foreach (ManagementObject o in objectCollection)
                    objects.Add(o);
            }
            catch (ManagementException me)
            {
                if (me.ErrorCode == ManagementStatus.NotSupported)
                {
                    throw new NotSupportedException(me.Message, me);
                }
                if (noisy)
                {
                    Debug.Print("Management Exception: " + me.ToString());
                    Debug.Flush();
                }
                objects = null;
            }
            catch (Exception ex)
            {
                if (noisy)
                {
                    Debug.Print("Exception: " + ex.ToString());
                    Debug.Flush();
                }
                objects = null;
            }

            return objects;
        }
    }
}
